package com.guass.nettyprotostuff.rpc.common;

import lombok.Data;
import lombok.ToString;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

public class SessionManager {
    private static volatile SessionManager instance = null;
    // netty生成的sessionID和Session的对应关系
    private Map<String, Session> sessionIdMap;
    // 终端手机号和netty生成的sessionID的对应关系
    private Map<String, SessionInfo> macMap;

    @Data
    @ToString
    public static class SessionInfo{
        String sessionId;
    }

    public static SessionManager getInstance() {
        if (instance == null) {
            synchronized (SessionManager.class) {
                if (instance == null) {
                    instance = new SessionManager();
                }
            }
        }
        return instance;
    }

    private SessionManager() {
        this.sessionIdMap = new ConcurrentHashMap<>();
        this.macMap = new ConcurrentHashMap<>();
    }

    public boolean containsKey(String sessionId) {
        return sessionIdMap.containsKey(sessionId);
    }

    public boolean containsSession(Session session) {
        return sessionIdMap.containsValue(session);
    }

    public Session findBySessionId(String id) {
        return sessionIdMap.get(id);
    }

    public Session findByTerminalMac(String mac) {

        SessionInfo info = this.macMap.get(mac);
        if (info == null) {
            return null;
        }
        return this.findBySessionId(info.getSessionId());
    }



    public synchronized Session put(String key, Session value) {
        if (value.getTerminalMac() != null && !"".equals(value.getTerminalMac().trim())) {
            SessionInfo sessionInfo = new SessionInfo();
            sessionInfo.setSessionId(value.getId());
            this.macMap.put(value.getTerminalMac(), sessionInfo);
        }
        return sessionIdMap.put(key, value);
    }

    public synchronized Session removeBySessionId(String sessionId) {
        if (sessionId == null) {
            return null;
        }
        Session session = sessionIdMap.remove(sessionId);
        if (session == null) {
            return null;
        }
        if (session.getTerminalMac() != null) {
            this.macMap.remove(session.getTerminalMac());
        }
        return session;
    }

    public Set<String> keySet() {
        return sessionIdMap.keySet();
    }


    public Set<Map.Entry<String, Session>> entrySet() {
        return sessionIdMap.entrySet();
    }

    /**
     * 判断终端是否在线
     * @param mac
     * @return
     */
    public synchronized boolean isOnlineFromMac(String mac){
        Session session = findByTerminalMac(mac);
        if (session != null && session.getChannel() != null && session.getChannel().isActive()){
            return true;
        }
        return false;
    }

    public List<Session> getSessions() {
        return this.sessionIdMap.entrySet().stream().map(e -> e.getValue()).collect(Collectors.toList());
    }

    public int getChannelCount() {
        return sessionIdMap.size();
    }
}
